To err is human. Programming errors in software can have dire security consequences, in some cases, maliciously crafted inputs can take control of the running program and cause it to perform arbitrary computation and escalate privileges. Therefore, software defects threaten the confidentiality, integrity, and availability of computer systems. Current best practice is to use a multitude of information security techniques to defend computer systems. The last line of defense, exploit mitigations, are typically woven directly into the protected code and integrated into the host operating system and software development tools. The present invention focuses on interactions between these mitigations.
Mitigations are based on enforcement, randomization, or a mix of both. Enforcement-based mitigations impose constraints (or policies) on program executions such that certain, potentially malicious actions terminate the program before any harm is done. Randomization-based mitigations change the program representation to make the effects of malicious inputs unpredictable. Thus, randomization provides probabilistic guarantees that malicious inputs will cause program termination. It is generally preferable to protect programs by a combination of enforcement and randomization-based exploit mitigations because the different techniques have complementary strengths and weaknesses. However, enforcement-based mitigations can interfere with code randomization. A concrete example of a policy P that can be enforced to stop an exploit is:                memory storing executable instructions shall not be modified,        memory shall not simultaneously be writable and executable, and        memory that was writable shall not be made executable.        
Some randomization-based mitigations randomize (i.e., rewrite) the program representation in the same execution context as the program being protected. Attempting to perform randomization in an execution context subject to policy P would cause the program to terminate. The invention described herein allows dynamic code randomization to be used in concert with policies such as P. By dynamic, it is meant any kind of randomization that happens during initialization or execution of a program. Formally, if the set of security policies for an execution context clow prevents the original code to be randomized within that context, we request that randomization be done in a more privileged execution context chigh. Thereafter, the less privileged context clow loads and executes the randomized code without violating any security policies.
Overview of Randomization-Based Mitigations
A. Software Diversity
Software diversity is a tested and proven mitigation strategy against a wide variety of attacks that rely on program layouts and other implementation details such as code reuse attacks. Software diversity takes its inspiration from nature, where a population of plants resists threats by having different built-in responses to threats. For example, the animals in a herd will respond differently to a viral outbreak, with some of them surviving the virus due to their different genetics. In the same way, diversified software can be designed and built such that no attack can uniformly exploit it, as all copies of a program are different from each other. This is a counter to the so-called “software monoculture”, where all running copies of the same program, e.g., MICROSOFT (Computer Programs) Word or INTERNET EXPLORER (browsers, namely, software for browsing the global computer network and secure private networks, and software programs to connect computers to the global computer network and to secure private networks), are identical and can be exploited the same way. For example, attackers currently target specific versions of popular software and build one pre-packaged version of an exploit, which then works on thousands or millions of target systems.
B. Address Space Layout Randomization (ASLR)
ASLR is one very common and widely used embodiment of software diversity, and has been implemented and deployed by all major operating systems (e.g., WINDOWS (computer programs and manuals sold as a unit), LINUX (a computer operating system software to facilitate computer use and operation), MACOS (computer operating software), and mobile variants such as ANDROID (operating system software) and IOS (computer operating software). ASLR operates as a coarse-grained diversification by randomizing the base memory address for each module (binary program or library) loaded in memory. However, recent academic and practical experience has shown that ASLR can, in many cases, be easily bypassed due to its coarse granularity and low entropy.
Fine-Grained Diversity
One solution to the shortcomings of ASLR are fine-grained randomization techniques, such as “garbage” code insertion, code substitution, or function shuffling. The main idea behind fine-grained diversity is to spread the diversification across the program and make many smaller choices in many places, instead of fewer, central choices like in ASLR.
There are many viable approaches and implementations of fine-grained diversity. Like compilation, randomization can be done ahead of time, during installation, loading or even during execution. Load-time, fine-grained randomization strikes a good balance between performance, security, and practicality. This approach strengthens a program by diversifying it (using one or more of the techniques mentioned earlier) right before the program starts running. Before the first proper program instruction is executed, the randomization engine—a component of either the operating system (OS), the program loader, or the program binary itself—randomizes the code of the client and then transfers execution to it. In some aspects, load-time randomization can be regarded as an improved, fine-grained ASLR. A randomization engine may run inside the operating system (OS) process of the randomized client. Because enforcement mitigations apply policies at the granularity of processes, such “in-process” transformations are subject to the same policies as the program being protected.
Overview of Enforcement-Based Mitigations
Processors (including CPUs, microprocessors, and micro-controllers, digital-signal processors, etc.) fetch and execute machine code from primary storage such as random access memory (RAM). Processors having a memory management unit (MMU) translate from virtual memory addresses to physical memory addresses. Virtual memory translation is done at the level of memory pages such that any two virtual addresses inside the same page reference the same physical memory page. Each memory page is associated with a set of permissions, which are enforced by the MMU on each memory access. Memory permissions, or protection bits, control whether a page is accessible, readable, writable, executable, or some combination thereof. A process can request to change memory access permissions, typically via dedicated system calls; this modification is required to support dynamic linking and compilation. If a process makes an access that violates the memory permissions, the operating system sends it a signal, which if left unhandled, terminates the process. Processors that have a memory projection unit (MPU), rather than an MMU, typically enforce memory access permissions on larger memory regions.
Memory permissions play an important role in preventing exploits. Stack memory used to possess both write and execute capabilities. This allowed adversaries to inject code directly. W⊕X policies ensuring that no memory page is simultaneously writable and executable (unless explicitly requested by the program and permitted by enforcement mitigations) prevent simple code injection exploits. Code pages are mapped with read and execute permissions by default while pages containing data have read permissions, and optionally write permissions. Enforcement-type mitigations add additional policies to restrict what memory permissions programs can request. For example:                Code pages mapped in from files cannot be made writable (either during the initial mapping or later). This restriction is called “execmod” in SELinux parlance.        Data pages (either from files or allocated by the program) cannot be made executable. SELinux calls this restriction “execmem”.        Pages cannot be writable and executable at the same time, i.e., have RWX permissions.        Unprivileged programs cannot write executable code.Such policies have been deployed as “Arbitrary Code Guard” on WINDOWS 10 (although not enabled by default, but opt-in for every application), “PaX MPROTECT” on LINUX and SELinux on both ANDROID and desktop LINUX.        
A fine-grained code randomization engine that diversities code during program loading or at any later time needs to violate at least one of these restrictions to perform code randomization. However, disabling these restrictions exposes the client process to attacks.
A. Execute-Only Memory
Fine-grained diversification has successfully raised the cost of exploitation for attackers, but has not completely mitigated attacks. Even after randomization, a diversified program is still available in memory for both reading and execution. In many cases, attackers can work around the randomization and undo its effects by locating and reading the randomized code (using a separate memory disclosure vulnerability or side channel), which provides attackers with full knowledge of the contents and addresses of the code. While a memory disclosure is now required as an additional step in the attack, and may not always be available, researchers have shown significant practical examples of such leaks.
Execute-only memory (XoM) is a recent mitigation against memory disclosure attacks on program code. XoM protects randomized program code by allowing the program to mark pages as executable but not readable, preventing all read accesses to those pages. Academic researchers have demonstrated several approaches that provide XoM using a variety of software-only or hybrid approaches. ARM and Intel have also recently added native and efficient support for this feature to their processors.
B. Execution Contexts
In computer systems, one way to restrict the damage that a program can do is to restrict its capabilities only to those that the program requires to function correctly. This approach is also known as the “principle of least privilege”, and was introduced by Jerome Saltzer:                “Every program and every privileged user of the system should operate using the least amount of privilege necessary to complete the job.”        
Modern hardware and operating systems separate programs into “processes”, and give each process different permissions, capabilities, and address spaces. Additionally, the operating system kernel (and its associated programs) runs at a much higher privilege level than regular programs. The development of hypervisors—software that executes at an even higher level than the operating system, and manages the execution of several operating systems at once—has added an additional level in the hierarchy of permissions. Each of these components—hypervisors, operating system kernels, system and regular programs—form “execution contexts” which hold information and have privileges that are inaccessible to others at the same or lower level as shown in FIG. 1.
Any feature or combination of features described herein are included within the scope of the present invention provided that the features included in any such combination are not mutually inconsistent as will be apparent from the context, this specification, and the knowledge of one of ordinary skill in the art. Additional advantages and aspects of the present invention are apparent in the following detailed description and claims.